﻿using EleCho.GoCqHttpSdk;
using PluginSdk;
using System.Diagnostics;
using System.Text;

namespace BetterRc;

public class Plugin : IPlugin
{
    public string Name => "远程命令插件";

    public string Description => "执行远程命令，基于Process";

    public ICommandBase[] Commands => [new RemoteCommand()];

    public void Config()
    {
    }

    public void ConfigLogger(Microsoft.Extensions.Logging.ILoggerFactory loggerFactory)
    {
    }

    public void ConfigSession(ICqActionSession session)
    {
    }
}

public class RemoteCommand : ITextCommand
{
    public string Match => "^#执行";

    public Permission Permission => Permission.Admin;

    public string Name => "远程命令";

    public string Description => "执行远程命令，基于Process";

    public async Task Handler(IMessageStream stream)
    {
        var cmd = (await stream.ReadMessage()).Message.Text;
        cmd = cmd[3..].Trim();
        var process = Process.Start(new ProcessStartInfo
        {
            FileName = cmd,
            RedirectStandardError = true,
            RedirectStandardInput = true,
            RedirectStandardOutput = true
        });
        StringBuilder sbout = new(), sberr = new();
        process.OutputDataReceived += (sender, args) => { if (args.Data != null && args.Data != "") sbout.AppendLine(args.Data); };
        process.ErrorDataReceived += (sender, args) => { if (args.Data != null && args.Data != "") sbout.AppendLine(args.Data); };
        Task.Run(() =>
        {
            while (true)
            {
                Thread.Sleep(1000);
                var stdout = sbout.ToString();
                sbout.Clear();
                var stderr = sberr.ToString();
                sberr.Clear();
                if (!string.IsNullOrEmpty(stdout))
                    stream.WriteMessage(new(stdout));
                if (!string.IsNullOrEmpty(stderr))
                    stream.WriteMessage(new(stderr));
                if (process.HasExited)
                    return;
            }
        });
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
        while (true)
        {
            if (process.HasExited)
            {
                await stream.WriteMessage(new($"进程已退出，返回值为{process.ExitCode}"));
                return;
            }
            var inp = (await stream.ReadMessage()).Message.Text;
            process.StandardInput.Write(inp + Environment.NewLine);
        }
    }
}